/**
 * Copyright 2006 Brad Reynolds
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.leeloo.databinding.internal.ui;

import org.eclipse.core.runtime.IAdapterFactory;
import org.leeloo.core.LeelooPlugin;
import org.leeloo.core.Tag;
import org.leeloo.core.TagService;
import org.leeloo.core.Tags;
import org.leeloo.databinding.ui.descriptor.BindingEventDescriptor;
import org.leeloo.databinding.ui.descriptor.DiffDescriptor;
import org.leeloo.databinding.ui.descriptor.ObservableDescriptor;
import org.leeloo.internal.core.ObjectDescriptor;

public class LabeledTreeNodeAdapterFactory implements IAdapterFactory {
    private final TagService tagService;

    public LabeledTreeNodeAdapterFactory() {
        tagService = LeelooPlugin.getDefault().getTagService();
    }

    public Object getAdapter(Object adaptableObject, Class adapterType) {
        Object result = null;
        if (adaptableObject instanceof ObjectDescriptor) {
            ObjectDescriptor descriptor = (ObjectDescriptor) adaptableObject;

            LabeledTreeNodeBuilder builder = LabeledTreeNodeBuilder.forNode(new LabeledTreeNode(descriptor));
            Tag nameTag = tagService.get(descriptor, Tags.NAME);
            if (nameTag == null) {
                nameTag = new Tag(Tags.NAME, null);
            }

            builder.addTagChild(nameTag, Messages.getString("LabeledTreeNodeAdapterFactory.name"), true); //$NON-NLS-1$
            builder.addChild(descriptor.getClassName(), Messages.getString("LabeledTreeNodeAdapterFactory.class_name")); //$NON-NLS-1$
            builder.addChild(new Integer(descriptor.getIdentityHashCode()),
                    Messages.getString("LabeledTreeNodeAdapterFactory.id")); //$NON-NLS-1$

            if (adaptableObject instanceof ObservableDescriptor) {
                ObservableDescriptor observable = (ObservableDescriptor) adaptableObject;
                builder.addChild(observable.getObservedDescriptor(),
                        Messages.getString("LabeledTreeNodeAdapterFactory.observed")); //$NON-NLS-1$

                // TODO this needs to be modeled some way
                Tag tag = tagService.get(observable, Databinding.PROPERTY_NAME);
                if (tag != null) {
                    builder.addTagChild(tag, Messages.getString("LabeledTreeNodeAdapterFactory.property_name"), false); //$NON-NLS-1$
                }
            }

            if (adaptableObject instanceof DiffDescriptor) {
                DiffDescriptor diff = (DiffDescriptor) adaptableObject;
                builder.addChild(diff.getToString(), Messages.getString("LabeledTreeNodeAdapterFactory.to_string")); //$NON-NLS-1$
            }

            if (adaptableObject instanceof BindingEventDescriptor) {
                BindingEventDescriptor bindingEvent = (BindingEventDescriptor) adaptableObject;
                builder.addChild(Databinding.getBindingEventName(bindingEvent.getCopyType()),
                        Messages.getString("LabeledTreeNodeAdapterFactory.event_type")); //$NON-NLS-1$
                builder.addChild(Databinding.getPipelinePositionName(bindingEvent.getPipelinePosition()),
                        Messages.getString("LabeledTreeNodeAdapterFactory.pipeline_position")); //$NON-NLS-1$
                builder.addChild(bindingEvent.getDiffDescriptor(),
                        Messages.getString("LabeledTreeNodeAdapterFactory.diff"), false); //$NON-NLS-1$
                builder.addChild(bindingEvent.getTargetObservableDescriptor(),
                        Messages.getString("LabeledTreeNodeAdapterFactory.target_observable"), false); //$NON-NLS-1$
                builder.addChild(bindingEvent.getModelObservableDescriptor(),
                        Messages.getString("LabeledTreeNodeAdapterFactory.model_observable"), false); //$NON-NLS-1$
            }

            result = builder.build();
        }

        return result;
    }

    private static final Class[] ADAPTER_LIST = new Class[] { ObjectDescriptor.class };

    public Class[] getAdapterList() {
        return ADAPTER_LIST;
    }
}